using System.Collections.Generic;
using Commons.Models.OperationsContext;
using Commons.Models.TradeValues;
using Commons.Services.Locks;
using Commons.Utils;

namespace Commons.Services.TradeValues
{
	public class ProbabilityRewardProcessor : IRewardProcessor
	{
		public IRewardProcessor Processor { protected get; set; }
		public ILockService LockService { protected get; set; }

		public IEnumerable<ITradeValue> PreProcessReward(ITradeValue value, IOperationContext context)
		{
			ProbabilityTradeValue tradeValue = value as ProbabilityTradeValue;

			List<ITradeValue> tradeValues = new List<ITradeValue>();

			if (LockService.CheckLock(tradeValue.Lock))
			{
				int probability = RandomHelper.GenerateRandom();
				ITradeValue randomTradeValue = tradeValue.GetValue(probability);
				
				if (randomTradeValue != null)
				{
					tradeValues.AddRange(Processor.PreProcessReward(randomTradeValue, context));
					CacheReward(randomTradeValue, context);
				}
			}

			return tradeValues;
		}

		public IEnumerable<ITradeValue> ProcessReward(ITradeValue value, IOperationContext context, int quantity)
		{
			List<ITradeValue> tradeValues = new List<ITradeValue>();

			if (LockService.CheckLock(value.Lock)) 
			{
				for (int i = 0; i < quantity; i++)
				{
					IEnumerable<ITradeValue> values = PreProcessReward(value, context);
					foreach (ITradeValue tradeValue in values)
					{
						tradeValues.AddRange(Processor.ProcessReward(tradeValue, context, 1));
					}
				}
			}

			return tradeValues;
		}

		protected void CacheReward(ITradeValue tradeValue, IOperationContext context)
		{
			if (context != null)
			{
				if (context.ContainsKey(ProbabilityTradeValue.ContextRewardKey))
				{
					context.Get<List<ITradeValue>>(ProbabilityTradeValue.ContextRewardKey).Add(tradeValue);
				}
				else if (context is BasicOperationContext)
				{
					BasicOperationContext basicContext = (BasicOperationContext) context;
					List<ITradeValue> tradeValues = new List<ITradeValue>();
					tradeValues.Add(tradeValue);
					basicContext.Add(ProbabilityTradeValue.ContextRewardKey, tradeValues);
				}
			}
		}
	}
}

